package com.shuke.sk_worm.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpUtil;
import com.shuke.sk_worm.consts.ShopPlatformEnum;
import com.shuke.sk_worm.domain.SkShopCookie;
import com.shuke.sk_worm.domain.SkShopInfo;
import com.shuke.sk_worm.service.*;
import com.shuke.sk_worm.tool.TimeUtil;
import com.shuke.sk_worm.tool.Worm;
import com.shuke.sk_worm.tool.hiskpi.Impl.JingdongShopImpl;
import com.shuke.sk_worm.tool.hiskpi.Impl.KuaishouShopImpl;
import com.shuke.sk_worm.tool.hiskpi.Impl.PingduoduoShopImpl;
import com.shuke.sk_worm.tool.hiskpi.Impl.TaobaoShopImpl;
import com.shuke.sk_worm.tool.hiskpi.ShopData;
import com.shuke.sk_worm.vo.ShopInfoListVo;
import org.apache.log4j.Logger;
import org.openqa.selenium.os.WindowsUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.*;

import java.awt.datatransfer.FlavorEvent;
import java.util.*;
import java.util.concurrent.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("job")
public class JobController {

    @Autowired
    private SkShopInfoService skShopInfoService;

    @Autowired
    private SkRealDataService skRealDataService;

    @Autowired
    private HisKpiService hisKpiService;

    @Autowired
    private SkShopCookieService cookieService;

    @Autowired
    private SysUserService userService;

    @Autowired
    private KuaishouShopImpl kuaishouShop;

    @Autowired
    private PingduoduoShopImpl pingduoduoShop;

    @Autowired
    private JingdongShopImpl jingdongShop;

    @Autowired
    private TaobaoShopImpl taobaoShop;

    @Value("${services.counts}")
    private Integer serviceCounts;

    @Value("${services.sorts}")
    private Integer serviceSorts;

    @Value("${services.deptId}")
    private Integer deptId;

    private static final Logger logger =  Logger.getLogger(JobController.class);

    @GetMapping("aaa")
    public void aa(){

        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);

        try {
            for (int i = 0; i<=5; i++){
                int finalI = i;
                FutureTask<Boolean> futureTask = new FutureTask<>(
                        new Callable<Boolean>() {
                            @Override
                            public Boolean call() throws Exception {
                                Thread.sleep(1000);
                                System.out.print("线程： " + String.valueOf(finalI));
                                return true;
                            }
                        }
                );
                fixedThreadPool.submit(futureTask);
            }
            fixedThreadPool.shutdown();

            while (!fixedThreadPool.awaitTermination(1, TimeUnit.SECONDS)) {
                System.out.println("等待所有任务执行完毕...");
            }


            System.out.println("等待所有任务执行完毕1111111");
        }catch (Exception e){
            System.out.print(e);
        }

    }

    @Scheduled(cron = "0 0 4 * * ?")
    @Async
    @GetMapping("sava_token")
    public void saveToken(){
        try {
            //杀掉所有的谷歌进程
            WindowsUtils.killByName("chromedriver.exe");
            WindowsUtils.killByName("chrome.exe");

            List<ShopInfoListVo> shopInfoList =  skShopInfoService.listShop(ShopPlatformEnum.DOUYIN);

            logger.info("[抖音]定时任务 Save_TOKEN start; 时间：" + System.currentTimeMillis());

            //获取店铺的cookie
            List<SkShopCookie> shopCookieList = cookieService.listShopCookie();
            Map<Long,SkShopCookie> shopCookie = new TreeMap<>();
            shopCookieList.forEach(shp->{
                shopCookie.put(shp.getShopId(), shp);
            });
            Worm worm = new Worm();

            //店铺Abnormal置为0
            //skShopInfoService.updateNotAbnormal(ShopPlatformEnum.DOUYIN);

            //先多线程跑出大部分数据
            List<ShopInfoListVo> shopInfoListVos = worm.multiSaveToken(shopInfoList, shopCookie);
           /* if (!shopInfoListVos.isEmpty()){
                worm.multiSaveToken(shopInfoList, shopCookie);
            }*/
            for(int i = 0; i < 4; i++){
                Thread.sleep(5 * 60 * 1000);
                //跑登录失败的店铺
                List<ShopInfoListVo> loginFailShops = skShopInfoService.listShopByLoginFail(ShopPlatformEnum.DOUYIN);
                logger.info("登录失败店铺数量：" + loginFailShops.size());
                if (loginFailShops != null){
                    worm.multiSaveToken(loginFailShops, shopCookie);
                }
            }


            //单线程跑出数据
            /*if (!shopInfoListVos.isEmpty()){
                worm.saveToken(shopInfoListVos, shopCookie);
            }*/

            //Long nowTimeMillis = System.currentTimeMillis();  //时间戳

            //Long nowTimeSecond = nowTimeMillis/1000;



            //没有更新token的店铺
            //List<SkShopInfo> shopInfos = skShopInfoService.listNotTokenShop(nowTimeSecond.intValue() - 72 * 3600, ShopPlatformEnum.DOUYIN);
            //if (!shopInfos.isEmpty()){
            //    skShopInfoService.updateAbnormal(shopInfos.stream().map(SkShopInfo::getId).collect(Collectors.toList()));
            //}

            logger.info("[抖音]定时任务 Save_TOKEN END; 时间： " + System.currentTimeMillis());

        }catch (Exception e){

        }
    }

    @GetMapping("login_fail")
    public void loginFailShops(){
        //杀掉所有的谷歌进程
        WindowsUtils.killByName("chromedriver.exe");
        WindowsUtils.killByName("chrome.exe");

        Worm worm = new Worm();

        //跑登录失败的店铺
        List<ShopInfoListVo> loginFailShops = skShopInfoService.listShopByLoginFail(ShopPlatformEnum.DOUYIN);
        logger.info("登录失败店铺数量：" + loginFailShops.size());
        if (loginFailShops != null){
            worm.multiSaveToken(loginFailShops, null);
        }
    }


    @Scheduled(cron = "0 40 12-19/6 * * ?")
    @Async
    public void saveThreeToken(){
        try {
            //杀掉所有的谷歌进程
            WindowsUtils.killByName("chromedriver.exe");
            WindowsUtils.killByName("chrome.exe");

            List<ShopInfoListVo> shopInfoList =  skShopInfoService.listShop(ShopPlatformEnum.DOUYIN);

            logger.info("[抖音]定时任务 Save_TOKEN（second） start; 时间：" + System.currentTimeMillis());

            //获取店铺的cookie
            List<SkShopCookie> shopCookieList = cookieService.listShopCookie();
            Map<Long,SkShopCookie> shopCookie = new TreeMap<>();
            shopCookieList.forEach(shp->{
                shopCookie.put(shp.getShopId(), shp);
            });

            //店铺Abnormal置为0
            //skShopInfoService.updateNotAbnormal(ShopPlatformEnum.DOUYIN);

            Worm worm = new Worm();
            //先多线程跑出大部分数据
            List<ShopInfoListVo> shopInfoListVos = worm.multiSaveToken(shopInfoList, shopCookie);

            for(int i = 0; i < 4; i++){
                Thread.sleep(5 * 60 * 1000);
                //跑登录失败的店铺
                List<ShopInfoListVo> loginFailShops = skShopInfoService.listShopByLoginFail(ShopPlatformEnum.DOUYIN);
                logger.info("登录失败店铺数量：" + loginFailShops.size());
                if (loginFailShops != null){
                    worm.multiSaveToken(loginFailShops, shopCookie);
                }
            }

            logger.info("[抖音]定时任务 Save_TOKEN（second） END; 时间： " + System.currentTimeMillis());
            //关闭所有的浏览器进程 (未找到为何webdriver已经退出，线程已经关闭，但是后台的浏览器进程未关闭)
            WindowsUtils.killByName("chrome.exe");
        }catch (Exception e){

        }
    }

    @Scheduled(cron = "0 0 23 * * ?")
    public void deleteInvalidToken(){
        try {
            Long nowTimeMillis = System.currentTimeMillis();  //时间戳
            Long nowTimeSecond = nowTimeMillis/1000 - 4 * 24 * 3600;
            cookieService.deleteShopCookie(nowTimeSecond.intValue());
            //杀掉所有的谷歌进程
            WindowsUtils.killByName("chromedriver.exe");
            WindowsUtils.killByName("chrome.exe");
        }catch (Exception e){

        }
    }

    @Scheduled(cron = "0 0 9-22/1 * * ?")
    @Async
    @GetMapping("real_data")
    public void realData(){
        List<ShopInfoListVo> shopInfoList =  skShopInfoService.listShop(ShopPlatformEnum.DOUYIN);
        logger.info("[抖音]定时任务 Real_DATA 店铺数量：" + shopInfoList.size());
        logger.info("[抖音]定时任务 Real_DATA start; 时间：" + System.currentTimeMillis());

        //获取店铺的cookie
        List<SkShopCookie> shopCookieList = cookieService.listShopCookie();
        Map<Long,String> shopCookie = new TreeMap<>();
        shopCookieList.forEach(shp->{
            shopCookie.put(shp.getShopId(), shp.getCookie());
        });

        skRealDataService.deleteBatch(ShopPlatformEnum.DOUYIN);


        Worm worm = new Worm();
        List<ShopInfoListVo> reShopInfoListVo = worm.realHttpData(shopInfoList, shopCookie, userService);
        int count = 0;
        int max = 4;

        while (ObjectUtil.isNotEmpty(reShopInfoListVo) && count < max){
            if (count > 0){
                try {
                    Thread.sleep(1000 * 60 * 2);
                }catch (Exception e){

                }
            }
            count++;
            reShopInfoListVo = worm.realHttpData(reShopInfoListVo, shopCookie, userService);
        }

        logger.info("[抖音]定时任务 Real_DATA END; 时间： " + System.currentTimeMillis());
    }


    @Scheduled(cron = "0 0 8 * * ?")
    @Async
    public void historyData(){
        try {
            logger.info("[抖音]定时任务 His_DATA start; 时间：" + System.currentTimeMillis());

            Date now = DateUtil.beginOfDay(DateUtil.date());
            Date yester = DateUtil.offsetDay(now, -1);

            history(yester);

            logger.info("[抖音]定时任务 His_DATA END; 时间： " + System.currentTimeMillis());
        }catch (Exception e){
            logger.info("[抖音]定时任务 His_DATA 异常：" + e);
        }
    }

    private void history(Date yester){
        List<ShopInfoListVo> shopInfoList =  skShopInfoService.listShop(ShopPlatformEnum.DOUYIN);

        //获取店铺的cookie
        List<SkShopCookie> shopCookieList = cookieService.listShopCookie();
        Map<Long,String> shopCookie = new TreeMap<>();
        shopCookieList.forEach(shp->{
            shopCookie.put(shp.getShopId(), shp.getCookie());
        });

        Date threeDay = DateUtil.offsetDay(yester, -2);

        hisKpiService.deleteData(threeDay.getTime(), yester.getTime(), ShopPlatformEnum.DOUYIN);

        Worm worm = new Worm();
        List<ShopInfoListVo> reShopInfoListVo = worm.hisHttpData(shopInfoList, shopCookie, userService, yester);
        int count = 0;
        int max = 4;

        while (ObjectUtil.isNotEmpty(reShopInfoListVo) && count < max){
            if (count > 0){
                try {
                    Thread.sleep(1000 * 60 * 2);
                }catch (Exception e){

                }
            }
            count++;
            reShopInfoListVo = worm.hisHttpData(reShopInfoListVo, shopCookie, userService, yester);
        }
    }

    @GetMapping("his_data_douyin")
    @Async
    public void historyDataHttp(@RequestParam(value = "time") String time){

        logger.info("[抖音]定时任务 His_DATA start; 时间：" + System.currentTimeMillis());

        history(DateUtil.parse(time));

        logger.info("[抖音]定时任务 His_DATA END; 时间： " + System.currentTimeMillis());
    }






    /**************                 快手 start                          *****************/

    private void realDataPlatform(ShopData shopData, Integer platform){
        //获取店铺信息
        List<ShopInfoListVo> shopInfoList =  skShopInfoService.listShop(platform);

        //获取店铺的cookie
        List<SkShopCookie> shopCookieList = cookieService.listShopCookie();
        Map<Long,String> shopCookie = new TreeMap<>();
        shopCookieList.forEach(shp->{
            shopCookie.put(shp.getShopId(), shp.getCookie());
        });

        //删除数据
        skRealDataService.deleteBatch(platform);

        shopData.realData(shopInfoList, shopCookie);
    }

    private void historyData(ShopData shopData, Integer platform, Date yester){
        //获取店铺信息
        List<ShopInfoListVo> shopInfoList =  skShopInfoService.listShop(platform);

        //获取店铺的cookie
        List<SkShopCookie> shopCookieList = cookieService.listShopCookie();
        Map<Long,String> shopCookie = new TreeMap<>();
        shopCookieList.forEach(shp->{
            shopCookie.put(shp.getShopId(), shp.getCookie());
        });

        Date threeDay = DateUtil.offsetDay(yester, -2);

        //删除三天的历史数据
        hisKpiService.deleteData(threeDay.getTime(), yester.getTime(), platform);

        //执行数据
        shopData.hiskpi(shopInfoList, shopCookie, yester);
    }

    //@Scheduled(cron = "0 30 8 * * ?")
    @GetMapping("his_data_kuaishou")
    public void historyKuaishou(){
        logger.info("[快手]定时任务 His_DATA start; 时间：" + System.currentTimeMillis());

        Date now = DateUtil.beginOfDay(DateUtil.date());
        Date yester = DateUtil.offsetDay(now, -1);
        historyData(kuaishouShop, ShopPlatformEnum.KUAISHOU, yester);

        logger.info("[快手]定时任务 His_DATA end; 时间：" + System.currentTimeMillis());
    }

    //@Scheduled(cron = "0 0 10-22/1 * * ?")
    @GetMapping("real_data_kuaishou")
    public void realDataKuaishou(){
        logger.info("[快手]定时任务 Real_DATA start; 时间：" + System.currentTimeMillis());

        realDataPlatform(kuaishouShop, ShopPlatformEnum.KUAISHOU);

        logger.info("[快手]定时任务 Real_DATA start; 时间：" + System.currentTimeMillis());
    }

    /**************                 快手 end                            *****************/

    /**************                 拼多多 start                        *****************/

    //@Scheduled(cron = "0 30 8 * * ?")
    @GetMapping("his_data_pinduoduo")
    public void historyPinduoduo(){
        logger.info("[拼多多]定时任务 His_DATA start; 时间：" + System.currentTimeMillis());

        Date now = DateUtil.beginOfDay(DateUtil.date());
        Date yester = DateUtil.offsetDay(now, -1);
        historyData(pingduoduoShop, ShopPlatformEnum.PINXI, yester);

        logger.info("[拼多多]定时任务 His_DATA end; 时间：" + System.currentTimeMillis());
    }


    //@Scheduled(cron = "0 0 10-22/1 * * ?")
    @GetMapping("real_data_pinduoduo")
    public void realDataPinduoduo(){
        logger.info("[拼多多]定时任务 Real_DATA start; 时间：" + System.currentTimeMillis());

        realDataPlatform(pingduoduoShop, ShopPlatformEnum.PINXI);

        logger.info("[拼多多]定时任务 Real_DATA start; 时间：" + System.currentTimeMillis());
    }

    /**************                 拼多多 end                        *****************/

    /**************                 京东 start                        *****************/

    //@Scheduled(cron = "0 0 10-22/1 * * ?")
    @GetMapping("his_data_jingdong")
    public void hisDataJingdong(){
        logger.info("[京东]定时任务 Real_DATA start; 时间：" + System.currentTimeMillis());

        Date now = DateUtil.beginOfDay(DateUtil.date());
        Date yester = DateUtil.offsetDay(now, -1);
        historyData(jingdongShop, ShopPlatformEnum.JINGDONG, yester);

        logger.info("[京东]定时任务 Real_DATA start; 时间：" + System.currentTimeMillis());
    }

    /**************                    京东 end                       *****************/

    /**************                 淘宝 start                        *****************/

    //@Scheduled(cron = "0 0 10-22/1 * * ?")
    @GetMapping("his_data_taobao")
    public void hisDataTaobao(){
        logger.info("[淘宝]定时任务 Real_DATA start; 时间：" + System.currentTimeMillis());

        Date now = DateUtil.beginOfDay(DateUtil.date());
        Date yester = DateUtil.offsetDay(now, -1);
        historyData(taobaoShop, ShopPlatformEnum.TAOBAO, yester);

        logger.info("[淘宝]定时任务 Real_DATA start; 时间：" + System.currentTimeMillis());
    }

    /**************                 淘宝 end                        *****************/
}
